/*
*       A simple 2D game map editor
*
*       This library is free software; you can redistribute it and/or
*       modify it under the terms of the GNU Lesser General Public
*       License as published by the Free Software Foundation; either
*       version 2.1 of the License, or (at your option) any later version.
*/
// Name        : mapwidget
// File        : mapwidget.cpp
// Description :
// Author      : hoha
// Date        : 01/07/2009
// Evolutions  : 01/07/2009, Version V0, Creation
#include "widget_map.h"
#include "gm_map.h"
#include <QRect>
#include <QMouseEvent>
#include <QRgb>
#include <QPen>

int locked_tile = 0;

void Wt_Map::init_border_grid()
{
	gmap_bs_point.setX(0);
	gmap_bs_point.setY(gmap_width*(TILE_HEIGHT/2));
	gmap_bl_point.setX(gmap_height*(TILE_WIDTH/2));
	gmap_bl_point.setY(wt_height);
	gmap_tr_point.setX(gmap_width*(TILE_WIDTH/2));
	gmap_tr_point.setY(0);
	gmap_br_point.setX(wt_width);
	gmap_br_point.setY(gmap_height*(TILE_HEIGHT/2));
}

Wt_Map::Wt_Map(QWidget *parent)
: QWidget(parent)
{
	//***********************************************
	//init game map size
  gmap_width = 20;
  gmap_height = 200;
	//init map window size
	wt_width = (gmap_width + gmap_height)*(TILE_WIDTH/2);
  wt_height = (gmap_width + gmap_height)*(TILE_HEIGHT/2);
	this->setMinimumSize(wt_width, wt_height);
	//init map border and grid
	this->init_border_grid();
	//init map memory
	gmap = NULL;
	this->init_map();
  this->gbase_tile = QPixmap("./tiles/base.png");
  gflag_grid = true;

	glock_tilex =0; //.setX(0);
  glock_tiley =0; //.setY(0);
	gcurrent_x = TILE_U16_NS;
	gcurrent_y = TILE_U16_NS;

	//***********************************************
}

Wt_Map::~Wt_Map()
{
	//free map memory
	for(int i=0; i< gmap_width; i++)
	{
		if(NULL!= gmap->map_core[i])
		{
			free(gmap->map_core[i]);
			gmap->map_core[i] = NULL;
		}
	}
	if(NULL!= gmap->map_core)
	{
		free(gmap->map_core);
		gmap->map_core = NULL;
	}
	if(NULL!= gmap)
	{
		free(gmap);
		gmap=NULL;
	}
}

void Wt_Map::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	for(int i=0; i<gmap_width; i++)
	{
		for(int j=0; j<gmap_height; j++)
		{
			if(TILE_U16_NS != gmap->map_core[i][j].tile_id)
			{
				int tileid = gmap->map_core[i][j].tile_id;
				painter.drawPixmap(gmap->map_core[i][j].screen_pos_x, gmap->map_core[i][j].screen_pos_y,\
						*memtileset->mem_entry[tileid].img_data_p,\
						0,0, memtileset->mem_entry[tileid].img_data_p->width(),\
						memtileset->mem_entry[tileid].img_data_p->height());
			}
			if(true == gflag_grid)
			{
				painter.drawPixmap(gmap->map_core[i][j].screen_pos_x, gmap->map_core[i][j].screen_pos_y,\
						this->gbase_tile, 0, 0, this->gbase_tile.width(),this->gbase_tile.height());
			}
		}
	}
	/*
	//painter.drawText(100,100,"what the fuck!");
	for(int i =0; i<20; i++)
	{

	for(int j =0; j<10; j++)
	{
	this->PosGameToScreen(gmap_bs_point.x(),gmap_bs_point.y(),\
	i, j, test_x, test_y);
	QString idx= QString::number(i);
	QString idy = QString::number(j);
	painter.drawText(test_x+20, test_y+20, idx);
	painter.drawText(test_x+20, test_y+30, idy);
	//painter.drawImage(test_x, test_y, *map_image, 0, 0, map_image->width(), map_image->height(), Qt::AutoColor);
	}
	}
	 */


}

void Wt_Map::mousePressEvent(QMouseEvent *event)
{
	this->PosScreenToGame(gmap_bs_point.x(),gmap_bs_point.y(),\
			event->x(), event->y(), glock_tilex, glock_tiley);
	this->fill_cell_with_tile(glock_tilex, glock_tiley, locked_tile);
	update();

}

void Wt_Map::mouseReleaseEvent(QMouseEvent *event)
{
	gcurrent_x = TILE_U16_NS;
	gcurrent_y = TILE_U16_NS;
}

void Wt_Map::mouseMoveEvent(QMouseEvent *event)
{
	this->PosScreenToGame(gmap_bs_point.x(),gmap_bs_point.y(),\
			event->x(), event->y(), glock_tilex, glock_tiley);
	if((glock_tilex!= gcurrent_x)||(glock_tiley != gcurrent_y))
	{
		gcurrent_x = glock_tilex;
		gcurrent_y = glock_tiley;
		this->fill_cell_with_tile(glock_tilex, glock_tiley, locked_tile);
		update();
	}
}


void Wt_Map::keyPressEvent(QKeyEvent *k)
{
}

void Wt_Map::keyReleaseEvent(QKeyEvent *k)
{
}

bool Wt_Map::fill_cell_with_tile(int map_x, int map_y, int tile_id)
{
	if((map_x >=0)&&(map_x<gmap_width)&&(map_y>=0)&&(map_y<gmap_height))
	{
		gmap->map_core[map_x][map_y].tile_id = tile_id;
	}
	return true;
}

bool Wt_Map::fill_map_with_tile(int tile_id)
{
	for( int x=0; x< gmap_width; x++)
	{
		for(int y =0; y< gmap_height; y++)
		{
			gmap->map_core[x][y].tile_id = tile_id;
		}
	}
	return true;
}

void Wt_Map::grid_show()
{
	gflag_grid = !gflag_grid;
	update();
}

bool Wt_Map::init_map()
{
	gmap = (map_t*)malloc(sizeof(map_t));
	if(NULL!=gmap)
	{
		gmap->head.version = 0;
		gmap->map_core = (map_core_t**)malloc(sizeof(map_core_t*)*gmap_width);
		if(NULL!= gmap->map_core)
		{
			for(int i=0; i< gmap_width; i++)
			{
				gmap->map_core[i] = (map_core_t*)malloc(sizeof(map_core_t)*gmap_height);
			}
		}
		else
		{
			printf("gmap->map_core memory allocation failed\n");
			return false;
		}
	}
	else
	{
		printf("gmap memory allocation failed!\n");
		return false;
	}
	for(int x=0; x< gmap_width; x++)
	{
		for(int y =0; y< gmap_height; y++)
		{
			this->PosGameToScreen(gmap_bs_point.x(),gmap_bs_point.y(),\
					x, y, (gmap->map_core[x][y].screen_pos_x), (gmap->map_core[x][y].screen_pos_y));
			gmap->map_core[x][y].tile_id = TILE_U16_NS;
		}
	}
	return true;
}

inline void Wt_Map::PosGameToScreen(int base_x, int base_y, int G_x, int G_y, int &S_x, int &S_y)
{
	S_x = (G_y + G_x) * (TILE_WIDTH>>1) + base_x;
	S_y = (G_y - G_x) * (TILE_HEIGHT>>1) -( TILE_HEIGHT>>1) + base_y;
}

inline void Wt_Map::PosScreenToGame(int base_x, int base_y, int S_x, int S_y, int &G_x, int &G_y )
{
	float fn, fm;
	fn = (S_x - base_x) / (TILE_WIDTH*1.0f) - (S_y - base_y) / (TILE_HEIGHT*1.0f);
	fm = (S_x - base_x) / (TILE_WIDTH*1.0f) + (S_y - base_y) / (TILE_HEIGHT*1.0f);

	if (fn < 0)
	{
		G_x = (int)fn - 1;
	}
	else
	{
		G_x = (int)fn;
	}

	if (fm < 0)
	{
		G_y = (int)fm - 1;
	}
	else
	{
		G_y = (int)fm;
	}
}

